package com.morningstar.common.advice;

import com.morningstar.common.exception.ApiException;
import com.morningstar.common.result.Result;
import com.morningstar.common.result.ResultCode;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


/**
 * 全局异常处理
 * @author yls
 */
@Slf4j
@ControllerAdvice
public class ControllerExceptionAdvice extends BaseExceptionAdvice {

    /**
     * 默认异常处理
     * @param exception         异常信息
     * @param request           请求实体
     * @return                  基本结果类
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Result<Object> defaultExceptionHandler(Exception exception, HttpServletRequest request) {
        log.error("default exception {} {}", exception.getMessage(), exception.getClass().getName());
        log.error(ExceptionUtils.getStackTrace(exception));
        return Result.fail(ResultCode.SERVER_EXCEPTION, exception.getMessage());
    }

    /**
     * api异常处理
     * @param apiException  异常信息
     * @param request       请求信息
     * @return              基本结果类
     */
    @ResponseBody
    @ExceptionHandler(value = ApiException.class)
    public Result<Object> apiExceptionHandler(ApiException apiException, HttpServletRequest request) {
        log.error("api_exception message {}", apiException.getMessage());
        log.error(ExceptionUtils.getStackTrace(apiException));
        return Result.fail(apiException.getResultCode(), apiException.getMessage());
    }

    /**
     * 绑定参数异常处理类
     * @param bindException     请求参数校验异常
     * @param request           请求信息
     * @return                  基本结果类
     */
    @ResponseBody
    @ExceptionHandler(value = BindException.class)
    public Result<Object> bindExceptionHandler(BindException bindException, HttpServletRequest request) {
        log.error("bind_exception message {}", bindException.getMessage());
        log.error(ExceptionUtils.getStackTrace(bindException));
        StringBuilder message = new StringBuilder("error msg");
        for (FieldError fieldError: bindException.getFieldErrors()) {
            log.info("field  {}  code {}", fieldError.getField(), fieldError.getCode());
            message.append("[").append(fieldError.getField()).append(":").append(fieldError.getCode()).append("]");
        }
        return Result.fail(ResultCode.REQUEST_PARAM_ERROR, message.toString());
    }
}
